package dao;

import java.util.Enumeration;
import java.util.Hashtable;

public abstract class ObjectsPool<T> {
	private long expirationTime;
	private Hashtable<T, Long> blocked;
	private Hashtable<T, Long> nonBlocked;

	public ObjectsPool() {
		expirationTime = 30000;
		blocked = new Hashtable<T, Long>();
		nonBlocked = new Hashtable<T, Long>();
	}

	protected abstract T create();

	public abstract boolean validate(T o);

	public abstract void expirate(T o);

	public synchronized T checkOut() {
		long now = System.currentTimeMillis();
		T o;
		if (nonBlocked.size() > 0) {
			Enumeration<T> e = nonBlocked.keys();
			while (e.hasMoreElements()) {
				o = e.nextElement();
				if ((now - nonBlocked.get(o).longValue()) > expirationTime) {
					// object has expired
					nonBlocked.remove(o);
					expirate(o);
					o = null;
				} else {
					if (validate(o)) {
						nonBlocked.remove(o);
						blocked.put(o, new Long(now));
						return (o);
					} else {
						// the object is not valid
						nonBlocked.remove(o);
						expirate(o);
						o = null;
					}
				}
			}
		}
		// there are not available objects, then we create a new one
		o = create();
		blocked.put(o, new Long(now));
		return (o);
	}

	public synchronized void checkIn(T o) {
		blocked.remove(o);
		nonBlocked.put(o, new Long(System.currentTimeMillis()));
	}
}
